﻿using GalaSoft.MvvmLight;
using wp7cinema.Model;
using System.Collections.Generic;
using System.Net;
using System;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
using System.Collections.ObjectModel;
using GalaSoft.MvvmLight.Command;
using wp7cinema.ExtendedMethod;
using Microsoft.Phone.Controls;
using System.Windows;
using System.Text.RegularExpressions;

namespace wp7cinema.ViewModel
{
    public class EnableDate
    {
        public string Key { get; set; }
        public string Value { get; set; }
    }
    public class TheaterSearchViewModel : ViewModelBase
    {
        MovieSimpleInfo simpleInfo;
        IEnumerable<string> theaters;
        SubRegion selectedRegion;
        MovieItem selectedMovie;
        IEnumerable<MovieItem> allMovies;
        EnableDate selectedDate;
        TheaterItem selectedTheater;

        #region 바인딩될 데이터들..
        private IEnumerable<MovieItem> _movies;
        public IEnumerable<MovieItem> Movies
        {
            get { return _movies; }
            set
            {
                _movies = value;
                RaisePropertyChanged("Movies");
            }
        }

        private IEnumerable<Region> _region1;
        public IEnumerable<Region> Region1
        {
            get { return _region1; }
            set
            {
                _region1 = value;
                RaisePropertyChanged("Region1");
            }
        }

        private IEnumerable<SubRegion> _region2;
        public IEnumerable<SubRegion> Region2
        {
            get { return _region2; }
            set
            {
                _region2 = value;
                RaisePropertyChanged("Region2");
            }
        }

        private IEnumerable<TheaterItem> _theaters;
        public IEnumerable<TheaterItem> Theaters
        {
            get { return _theaters; }
            set
            {
                _theaters = value;
                RaisePropertyChanged("Theaters");
            }
        }

        private List<EnableDate> _enableDates;
        public List<EnableDate> EnableDates
        {
            get { return _enableDates; }
            set
            {
                _enableDates = value;
                RaisePropertyChanged("EnableDates");
            }
        }

        private IEnumerable<TicketInfo> _tickets;
        public IEnumerable<TicketInfo> Tickets
        {
            get { return _tickets; }
            set
            {
                _tickets = value;
                RaisePropertyChanged("Tickets");
            }
        }
        #endregion

        #region Command 들...

        #region ListPicker 버그로 임시(?)수정

        //public RelayCommand<TheaterItem> SetTheaterCommand { get; set; }
        public void SetTheaterCommandExecute(TheaterItem theater)
        {
            if (theater == null) return;
            selectedTheater = theater;
            getTicketingInfo();
            //theater.SetResource("TheaterInfo");
            //selectedMovie.SetResource("MovieInfo");
            //allMovies.SetResource("AllMovies");
        }
        //public RelayCommand<MovieItem> SetMovieCommand { get; set; }
        public void SetMovieCommandExecute(MovieItem movie)
        {
            if (movie == null) return;
            Theaters = null;
            selectedMovie = movie;
            getTheaters(movie.Key);
        }

        //public RelayCommand<Region> SetSubRegionCommand { get; set; }
        public void SetSubRegionCommandExecute(Region region)
        {
            if (region == null) return;
            Region2 = region.SubRegions;
        }

        //public RelayCommand<SubRegion> SetTheatersCommand { get; set; }
        public void SetTheatersCommandExecute(SubRegion region)
        {
            if (region == null)
            {
                Theaters = null;
                return;
            }
            if (theaters == null) return;
            selectedRegion = region;
            Theaters = region.TheaterItems.Where(item =>
            {
                if (theaters.Contains(item.Key))
                    return true;
                return false;
            });
        }
        #endregion

        public RelayCommand<ListPicker> SetTheaterCommand { get; set; }
        public void SetTheaterCommandExecute(ListPicker listPicker)
        {
            TheaterItem theater = listPicker.SelectedItem as TheaterItem;
            SetTheaterCommandExecute(theater);
        }

        public RelayCommand<ListPicker> SetMovieCommand { get; set; }
        public void SetMovieCommandExecute(ListPicker listPicker)
        {
            MovieItem movie = listPicker.SelectedItem as MovieItem;
            SetMovieCommandExecute(movie);
        }

        public RelayCommand<ListPicker> SetSubRegionCommand { get; set; }
        public void SetSubRegionCommandExecute(ListPicker listPicker)
        {
            Region region = listPicker.SelectedItem as Region;
            SetSubRegionCommandExecute(region);
        }

        public RelayCommand<ListPicker> SetTheatersCommand { get; set; }
        public void SetTheatersCommandExecute(ListPicker listPicker)
        {
            SubRegion region = listPicker.SelectedItem as SubRegion;
            SetTheatersCommandExecute(region);
        }

        public RelayCommand<ListPicker> SetDateCommand { get; set; }
        public void SetDateCommandExecute(ListPicker listPicker)
        {
            EnableDate date = listPicker.SelectedItem as EnableDate;
            if (date == null) return;
            selectedDate = date;
            //getTicketingInfo();
        }

        public RelayCommand<TicketInfo> SetTicketInfo { get; set; }
        public void SetTicketInfoExecute(TicketInfo info)
        {
            if (info == null) return;
            string url = "http://movie.naver.com/movie/reservation/ticketingInfo2.nhn?movie="
                + selectedMovie.Key + "&theater=" + selectedTheater.Key + "&date=" + selectedDate + "&time=" + info.Time + "&seats=1&hall=" + info.ID;
            WebClient client = new WebClient();
            client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
            client.DownloadStringAsync(new Uri(url));
        }
        void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            string xmlStr = e.Result.Replace("&", "");
            XDocument xdoc = XDocument.Parse(xmlStr);
            string seats = xdoc.Root.Element("ticket").Attribute("seats").Value;
            MessageBox.Show("잔여좌석 : " + seats);
        }
        #endregion

        #region 생성자

        public TheaterSearchViewModel()
        {
            //SetMovieCommand = new RelayCommand<MovieItem>(SetMovieCommandExecute);
            //SetSubRegionCommand = new RelayCommand<Region>(SetSubRegionCommandExecute);
            //SetTheatersCommand = new RelayCommand<SubRegion>(SetTheatersCommandExecute);
            //SetTheaterCommand = new RelayCommand<TheaterItem>(SetTheaterCommandExecute);
            SetMovieCommand = new RelayCommand<ListPicker>(SetMovieCommandExecute);
            SetSubRegionCommand = new RelayCommand<ListPicker>(SetSubRegionCommandExecute);
            SetTheatersCommand = new RelayCommand<ListPicker>(SetTheatersCommandExecute);
            SetTheaterCommand = new RelayCommand<ListPicker>(SetTheaterCommandExecute);
            SetDateCommand = new RelayCommand<ListPicker>(SetDateCommandExecute);
            SetTicketInfo = new RelayCommand<TicketInfo>(SetTicketInfoExecute);

            if (IsInDesignMode)
            {
                #region 디자인용 더미데이터
                Movies = new ObservableCollection<MovieItem> {
                    new MovieItem { Title = "아저씨" },
                    new MovieItem { Title = "아저씨(3D)" },
                    new MovieItem { Title = "아저씨(4bit)" },
                    new MovieItem { Title = "아저씨(디지털)" }
                };
                Region1 = new ObservableCollection<Region> {
                    new Region { Title = "서울" },
                    new Region { Title = "경기도" },
                    new Region { Title = "충청도" },
                    new Region { Title = "광주/전라/제주" }
                };
                Region2 = new ObservableCollection<SubRegion> {
                    new SubRegion { Title = "목포" },
                    new SubRegion { Title = "광주" },
                    new SubRegion { Title = "순천" },
                    new SubRegion { Title = "장성" }
                };
                Theaters = new ObservableCollection<TheaterItem> {
                    new TheaterItem { Name = "CGV" },
                    new TheaterItem { Name = "프리머스" },
                    new TheaterItem { Name = "롯데시네마" },
                    new TheaterItem { Name = "메가박스" }
                };
                EnableDates = new List<EnableDate> {
                    new EnableDate { Key="20100822", Value="08월 22일 금요일" }
                };
                Tickets = new ObservableCollection<TicketInfo> {
                    new TicketInfo { ViewStr = "1관 13 : 20" },
                    new TicketInfo { ViewStr = "1관 13 : 20" },
                    new TicketInfo { ViewStr = "1관 13 : 20" },
                    new TicketInfo { ViewStr = "1관 13 : 20" }
                };
                #endregion
            }
            else
            {
                #region 디자인용 더미데이터
                Movies = new ObservableCollection<MovieItem> {
                    new MovieItem { Title = "해리포터" },
                    new MovieItem { Title = "해리포터(3D)" },
                    new MovieItem { Title = "해리포터(4bit)" },
                    new MovieItem { Title = "해리포터(디지털)" }
                };
                Region1 = new ObservableCollection<Region> {
                    new Region { Title = "서울" },
                    new Region { Title = "경기도" },
                    new Region { Title = "충청도" },
                    new Region { Title = "광주/전라/제주" }
                };
                Region2 = new ObservableCollection<SubRegion> {
                    new SubRegion { Title = "목포" },
                    new SubRegion { Title = "광주" },
                    new SubRegion { Title = "순천" },
                    new SubRegion { Title = "장성" }
                };
                Theaters = new ObservableCollection<TheaterItem> {
                    new TheaterItem { Name = "CGV" },
                    new TheaterItem { Name = "프리머스" },
                    new TheaterItem { Name = "롯데시네마" },
                    new TheaterItem { Name = "메가박스" }
                };
                EnableDates = new List<EnableDate> {
                    new EnableDate { Key="20100822", Value="08월 22일 금요일" }
                };
                Tickets = new ObservableCollection<TicketInfo> {
                    new TicketInfo { ViewStr = "1관 13 : 20" },
                    new TicketInfo { ViewStr = "1관 13 : 20" },
                    new TicketInfo { ViewStr = "1관 13 : 20" },
                    new TicketInfo { ViewStr = "1관 13 : 20" }
                };
                #endregion

                //getAllTicketingInfo();
            }
        }
        #endregion

        #region 선택된영화 상영중인 극장목록 다운로드

        private string getTheaters(string code)
        {
            string url = "http://movie.naver.com/movie/reservation/ticketingInfo2.nhn?movie=" + code;
            WebClient client2 = new WebClient();
            client2.DownloadStringCompleted += new DownloadStringCompletedEventHandler(TicketingInfoDownloaded);
            client2.DownloadStringAsync(new Uri(url));
            return url;
        }
        void TicketingInfoDownloaded(object sender, DownloadStringCompletedEventArgs e)
        {
            XDocument xdoc = XDocument.Parse(e.Result);

            theaters = xdoc.Root.Element("theaters").Descendants("item")
                .Select(item => item.Attribute("key").Value);

            if (selectedRegion != null) SetTheatersCommandExecute(selectedRegion);
        }
        #endregion

        #region 전체 영화목록 및 극장목록 다운로드

        private void getAllTicketingInfo()
        {
            simpleInfo = App.Current.Resources["MovieSimpleInfo"] as MovieSimpleInfo;

            string url = "http://movie.naver.com/movie/reservation/ticketingInfo2.nhn";
            WebClient client = new WebClient();
            client.DownloadStringCompleted += AllTicketingInfoDownloaded;
            client.DownloadStringAsync(new Uri(url));

            url = getTheaters(simpleInfo.DetailViewCode + "_0");
        }
        void AllTicketingInfoDownloaded(object sender, DownloadStringCompletedEventArgs e)
        {
            XDocument xdoc = XDocument.Parse(e.Result);
            int i = 0;
            allMovies = xdoc.Root.Element("movies").Descendants("item")
                .Select(item => new MovieItem
               {
                   Key = item.Attribute("key").Value,
                   Title = item.Value
               });
            Movies = allMovies.Where(item =>
               {
                   if (item.Key.IndexOf(simpleInfo.DetailViewCode) == -1)
                       return false;
                   item.Title = ++i + ". " + item.Title;
                   return true;
               });
            selectedMovie = Movies.Where(item =>
            {
                if (item.Key == simpleInfo.DetailViewCode + "_0")
                    return true;
                return false;
            }).First();

            Region1 = xdoc.Root.Element("theaters").Descendants("region1")
                .Select(region1 => new Region {
                    Title = region1.Attribute("title").Value,
                    SubRegions = region1.Descendants("region2")
                    .Select( region2 => new SubRegion {
                        Title = region2.Attribute("title").Value,
                        TheaterItems = region2.Descendants("item")
                        .Select( item => new TheaterItem {
                                Key = item.Attribute("key").Value,
                                Name = item.Attribute("name").Value
                            })
                    })
                });
        }
        #endregion


        #region 티켓정보(영화목록, 날짜, 시간) 다운로드

        WebClient client;
        private void getTicketingInfo()
        {
            string url = "http://movie.naver.com/movie/reservation/ticketingInfo2.nhn?movie=" + selectedMovie.Key + "&theater=" + selectedTheater.Key;
            if (selectedDate != null) url += "&date=" + selectedDate.Key;
            client = new WebClient();
            client.DownloadStringCompleted += TicketingInfoDownloaded2;
            client.DownloadStringAsync(new Uri(url));
        }
        void TicketingInfoDownloaded2(object sender, DownloadStringCompletedEventArgs e)
        {
            client.DownloadStringCompleted -= TicketingInfoDownloaded2;
            XDocument xdoc = XDocument.Parse(e.Result);

            List<EnableDate> enableDates = null;
            XAttribute dateEnableAttr = xdoc.Root.Element("dates").Attribute("dateEnable");
            if (dateEnableAttr != null)
            {
                MatchCollection matches = Regex.Matches(dateEnableAttr.Value, "([0-9]{4})([0-9]{2})([0-9]{2})");
                enableDates = new List<EnableDate>();
                EnableDate enableDate;
                foreach (Match m in matches)
                {
                    int year = Convert.ToInt32(m.Groups[1].Value);
                    int month = Convert.ToInt32(m.Groups[2].Value);
                    int day = Convert.ToInt32(m.Groups[3].Value);
                    DateTime date = new DateTime(year, month, day);
                    string week = "";
                    switch (date.DayOfWeek)
                    {
                        case DayOfWeek.Monday: week = "월요일"; break;
                        case DayOfWeek.Tuesday: week = "화요일"; break;
                        case DayOfWeek.Wednesday: week = "수요일"; break;
                        case DayOfWeek.Thursday: week = "목요일"; break;
                        case DayOfWeek.Friday: week = "금요일"; break;
                        case DayOfWeek.Saturday: week = "토요일"; break;
                        case DayOfWeek.Sunday: week = "일요일"; break;
                    }
                    enableDate = new EnableDate { Key = m.Value, Value = m.Groups[2].Value + "월 " + m.Groups[3].Value + "일 " + week };
                    enableDates.Add(enableDate);
                }
                //enableDates = dateEnable.Split(new string[] { "||" }, StringSplitOptions.RemoveEmptyEntries).ToList();
            }
            int notIncludeCount = 0;
            // 날짜가 같으면 변경하지 않음.
            if (EnableDates != null && enableDates != null)
            {
                notIncludeCount = enableDates.Where(date =>
                {
                    if (EnableDates.Contains(date)) return false;
                    return true;
                }).Count();
            }
            if (EnableDates != null && enableDates != null && notIncludeCount == 0 && EnableDates.Count == enableDates.Count)
            {
            }
            else EnableDates = enableDates;

            XElement tickets = xdoc.Root.Element("tickets");
            if (tickets != null)
            {
                Tickets = tickets.Elements("info")
                    .Select(info =>
                    {
                        string str = Regex.Replace(info.Attribute("place").Value + info.Attribute("time").Value, "(.{1,3})(\\.?)([0-9]{2})([0-9]{2})", "$1 $3 : $4");
                        return new TicketInfo
                        {
                            ViewStr = str,
                            ID = info.Attribute("id").Value,
                            Time = info.Attribute("time").Value
                        };
                    });
            }
        }
        #endregion
    }
}